#include "Sprite.h"

dkm::Sprite::Sprite(string imgSrc, ID3DXSprite* dxSprite, const float x, const float y, const float width, const float height, const float rotation, const float scaleX, const float scaleY, const bool visible, const bool active)
	:Component(visible, active)
	,dxSprite(dxSprite)
	,texture(dkm::Engine::GetInstance()->AddTex(imgSrc))
	,x(x)
	,y(y)
	,depth(0.0f)
	,width(width)
	,height(height)
	,rotation(rotation)
	,scaleX(scaleX)
	,scaleY(scaleY)
	,drawMode("T")
	,isBatched(false)
	,pos(0.0f,0.0f,0.0f)
	,center(width/2.0f,height/2.0f,0.0f)
	,useRect(false)
{
	dkm::Engine::GetInstance()->AddComponent(this);
}

// visible and active are true is not specified
dkm::Sprite::Sprite(string imgSrc, ID3DXSprite* dxSprite, const float x, const float y, const float width, const float height, const float rotation, const float scaleX, const float scaleY)
	:Component(true,true)
	,dxSprite(dxSprite)
	,texture(dkm::Engine::GetInstance()->AddTex(imgSrc))
	,x(x)
	,y(y)
	,depth(0.0f)
	,width(width)
	,height(height)
	,rotation(rotation)
	,scaleX(scaleX)
	,scaleY(scaleY)
	,drawMode("T")
	,isBatched(false)
	,pos(0.0f,0.0f,0.0f)
	,center(width/2.0f,height/2.0f,0.0f)
	,useRect(false)
{
	dkm::Engine::GetInstance()->AddComponent(this);
}

dkm::Sprite::Sprite(IDirect3DTexture9* texture, ID3DXSprite* dxSprite, const float x, const float y, const float width, const float height, const float rotation, const float scaleX, const float scaleY, const bool visible, const bool active)
	:Component(visible, active)
	,dxSprite(dxSprite)
	,texture(texture)
	,x(x)
	,y(y)
	,depth(0.0f)
	,width(width)
	,height(height)
	,rotation(rotation)
	,scaleX(scaleX)
	,scaleY(scaleY)
	,drawMode("T")
	,isBatched(false)
	,pos(0.0f,0.0f,0.0f)
	,center(width/2.0f,height/2.0f,0.0f)
	,useRect(false)
{
	dkm::Engine::GetInstance()->AddComponent(this);
}

// visible and active are true is not specified
dkm::Sprite::Sprite(IDirect3DTexture9* texture, ID3DXSprite* dxSprite, const float x, const float y, const float width, const float height, const float rotation, const float scaleX, const float scaleY)
	:Component(true,true)
	,dxSprite(dxSprite)
	,texture(texture)
	,x(x)
	,y(y)
	,depth(0.0f)
	,width(width)
	,height(height)
	,rotation(rotation)
	,scaleX(scaleX)
	,scaleY(scaleY)
	,drawMode("T")
	,isBatched(false)
	,pos(0.0f,0.0f,0.0f)
	,center(width/2.0f,height/2.0f,0.0f)
	,useRect(false)
{
	dkm::Engine::GetInstance()->AddComponent(this);
}

dkm::Sprite::~Sprite()
{
	dkm::Engine::GetInstance()->RemoveComponent(this);
}

void dkm::Sprite::Update(const float dt)
{
	if (!isActive) return;	
}

void dkm::Sprite::Draw()
{	
	if (isBatched) return;

	//HR(gd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, true));
	
	if (drawMode != "") Transform();

	if (useRect)
	{
		HR(dxSprite->Draw(texture, &r, &center, &D3DXVECTOR3(0.0f, 0.0f, depth), D3DCOLOR_XRGB(255,255,255)));
	}
	else
	{
		HR(dxSprite->Draw(texture, 0, &center, &D3DXVECTOR3(0.0f, 0.0f, depth), D3DCOLOR_XRGB(255,255,255)));
	}

	HR(dxSprite->Flush());

	//HR(gd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false));
}

void dkm::Sprite::DrawBatched()
{
	if (!isVisible) return;	
	
	if (drawMode != "") Transform();

	if (useRect)
	{
		HR(dxSprite->Draw(texture, &r, &center, &D3DXVECTOR3(0.0f, 0.0f, depth), D3DCOLOR_XRGB(255,255,255)));
	}
	else
	{
		HR(dxSprite->Draw(texture, 0, &center, &D3DXVECTOR3(0.0f, 0.0f, depth), D3DCOLOR_XRGB(255,255,255)));
	}
}

void dkm::Sprite::Transform()
{
	if (drawMode == "R")
	{
		D3DXMatrixRotationZ(&R, rotation);
		HR(dxSprite->SetTransform(&R));
	}
	else if (drawMode == "T")
	{
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		HR(dxSprite->SetTransform(&T));
	}
	else if (drawMode == "S")
	{
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&S));
	}
	else if (drawMode == "RT")
	{
		D3DXMatrixRotationZ(&R, rotation);
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		HR(dxSprite->SetTransform(&(R*T)));
	}
	else if (drawMode == "RS")
	{
		D3DXMatrixRotationZ(&R, rotation);
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&(R*S)));
	}
	else if (drawMode == "TR")
	{
		D3DXMatrixRotationZ(&R, rotation);
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		HR(dxSprite->SetTransform(&(T*R)));
	}
	else if (drawMode == "TS")
	{
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&(T*S)));
	}
	else if (drawMode == "SR")
	{
		D3DXMatrixRotationZ(&R, rotation);
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&(S*R)));
	}
	else if (drawMode == "ST")
	{
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&(S*T)));
	}
	else if (drawMode == "RST")
	{
		D3DXMatrixRotationZ(&R, rotation);
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&(R*S*T)));
	}
	else if (drawMode == "RTS")
	{
		D3DXMatrixRotationZ(&R, rotation);
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&(R*T*S)));

	}
	else if (drawMode == "TRS")
	{
		D3DXMatrixRotationZ(&R, rotation);
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&(T*R*S)));
	}
	else if (drawMode == "TSR")
	{
		D3DXMatrixRotationZ(&R, rotation);
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&(T*S*R)));
	}	
	else if (drawMode == "SRT")
	{
		D3DXMatrixRotationZ(&R, rotation);
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&(S*R*T)));
	}
	else if (drawMode == "STR")
	{
		D3DXMatrixRotationZ(&R, rotation);
		D3DXMatrixTranslation(&T, x, y, 0.0f);
		D3DXMatrixScaling(&S,scaleX,scaleY,1.0f);
		HR(dxSprite->SetTransform(&(S*T*R)));
	}
}

void dkm::Sprite::SetRect(const bool useRect, const float left, const float top, const float right, const float bottom)
{
	if (useRect)
	{
		this->useRect = true;
		r.left = left;
		r.top = top;
		r.right = right;
		r.bottom = bottom;
	}
	else
	{
		this->useRect = false;
	}
}

void dkm::Sprite::SetRect(const bool useRect)
{
	SetRect(useRect, 0.0f, 0.0f, 0.0f, 0.0f);
}